﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using crm_dal.Objects;
using crm_library.Extenstions;
using System.ServiceModel;
using crm_services.WCF.MakeASale;
using crm_library.Javascript;

namespace crm_web.TaskPages
{
	public partial class MakeASale : System.Web.UI.Page
	{
		private class ClientControl : UserControl
		{
			private DropDownList ClientList;

			private TextBox FirstName;
			private TextBox MiddleInit;
			private TextBox LastName;
			private TextBox Company;

			public ClientControl()
			{
				ClientList = new DropDownList { AutoPostBack = true };
				ClientList.SelectedIndexChanged += new EventHandler(ClientList_SelectedIndexChanged);

				ClientList.Items.Add(new ListItem("New Client", "-1"));
				ClientList.Items.AddRange(Client.GetAll().Select(client => client.ToListItem()).ToArray());

				FirstName = new TextBox();
				MiddleInit = new TextBox();
				LastName = new TextBox();
				Company = new TextBox();
			}

			private void ClientList_SelectedIndexChanged(object sender, EventArgs e)
			{
				if (ClientList.SelectedValue == "-1")
				{
					FirstName.Text = "";
					MiddleInit.Text = "";
					LastName.Text = "";
					Company.Text = "";
				}
				else
				{
					var value = int.Parse(ClientList.SelectedValue);
					PopulateFromClient(new Client(value));
				}
			}

			public void PopulateFromClient(Client client)
			{
				ClientList.SelectedValue = client.ClientID.ToString();
				FirstName.Text = client.FirstName;
				MiddleInit.Text = client.MiddleInit;
				LastName.Text = client.LastName;
				Company.Text = client.Company;

			}

			public Client ToClient()
			{
				var client = new Client
					{
						ClientID = int.Parse(ClientList.SelectedValue),
						FirstName = FirstName.Text.Trim(),
						MiddleInit = MiddleInit.Text.Trim(),
						LastName = LastName.Text.Trim(),
						Company = Company.Text.Trim()
					};

				return client;
			}

			protected override void CreateChildControls()
			{
				base.CreateChildControls();

				var pane = new Panel
								{
									CssClass="ClientControlPane ControlPane"
								};

				
				var table = new Table();
				pane.Controls.Add(table);

				table.AddGeneratedRow("Client: ".ToLiteral(), ClientList, "Company: ".ToLiteral(), Company);
				table.AddGeneratedRow("First Name: ".ToLiteral(), FirstName, "Middle Init: ".ToLiteral(), MiddleInit, "Last Name: ".ToLiteral(), LastName);

				Controls.Add(pane);
			}
		}

		private class SaleControl : UserControl
		{
			private DropDownList UserList;

			private Button UpdateTotal;

			private List<SaleItemControl> SaleItems { get; set; }

			public SaleControl()
			{
				UserList = new DropDownList { AutoPostBack = true };
				UserList.Items.AddRange(crm_dal.Objects.User.GetAll().Select(user => user.ToListItem()).ToArray());

				UpdateTotal = new Button { Text = "Update Total" };

				SaleItems = new List<SaleItemControl>();
				foreach (var prod in Product.GetAll())
				{
					SaleItems.Add(new SaleItemControl(prod));
				}

			}


			public void PopulateFromClient(Sale sale)
			{
				UserList.SelectedValue = sale.UserID.ToString();

			}

			

			protected override void CreateChildControls()
			{
				base.CreateChildControls();

				var pane = new Panel
								{
									CssClass = "SaleControlPane ControlPane"
								};

				
				var table1 = new Table();
				table1.AddGeneratedRow("Sales Agent: ".ToLiteral(), UserList, UpdateTotal);
				pane.Controls.Add(table1);

				var table2 = new Table();
				table2.Rows.Add(SaleItemControl.Header);
				table2.Rows.AddRange(SaleItems.ToArray());
				table2.AddGeneratedRow("", "", "", "Sub Total:", FinalTotalLiteral);
				pane.Controls.Add(table2);
				
				Controls.Add(pane);
			}

			public decimal FinalTotal
			{
				get
				{
					decimal total = 0;

					foreach (var saleItem in SaleItems)
					{
						total += saleItem.LineTotal;
					}
					return total;
				}
			}
			private Literal _finalTotalLiteral;
			private Literal FinalTotalLiteral
			{
				get
				{
					if (_finalTotalLiteral == null)
					{
						_finalTotalLiteral = String.Format("{0:c}", FinalTotal).ToLiteral();
					}
					return _finalTotalLiteral;
				}
			}

			public void UpdateAll()
			{
				foreach (var item in SaleItems)
				{
					item.Update();
				}
				FinalTotalLiteral.Text = String.Format("{0:c}", FinalTotal);
			}

			public Sale ToSale()
			{
				var sale = new Sale()
								{
									Date = DateTime.Now,
									UserID = int.Parse(UserList.SelectedValue),
								};

				sale.SaleItems = SaleItems.Select(item => item.ToSaleItem()).ToList();

				return sale;
			}

		}

		private class SaleItemControl : TableRow
		{
			public Product Prod { get; set; }

			public SaleItemControl(Product product) 
			{ 
				Prod = product;
				QuantityTb = new TextBox
									{
										ID = "Qty_" + product.ProductID,
										ClientIDMode = System.Web.UI.ClientIDMode.Static
									};

				this.AddGeneratedTableCell(IDLiteral);
				this.AddGeneratedTableCell(NameLiteral);
				this.AddGeneratedTableCell(PriceLiteral);
				this.AddGeneratedTableCell(QuantityTb);
				this.AddGeneratedTableCell(LineTotalLiteral);
			}

			private TextBox QuantityTb;

			public int ID
			{
				get
				{
					return Prod.ProductID;
				}
			}
			public Literal IDLiteral
			{
				get
				{
					return ID.ToString().ToLiteral();
				}
			}

			public string Name
			{
				get
				{
					return Prod.ProductName;
				}
			}
			public Literal NameLiteral
			{
				get
				{
					return Name.ToLiteral();
				}
			}

			public decimal Price
			{
				get
				{
					return Prod.Price;
				}
			}
			public Literal PriceLiteral
			{
				get
				{
					return String.Format("{0:c}", Price).ToLiteral();
				}
			}

			public int Quantity
			{
				get
				{
					int value = 0;
					int.TryParse(QuantityTb.Text, out value);
					return value;
				}
				set
				{
					QuantityTb.Text = value.ToString();
				}
			}


			public decimal LineTotal
			{
				get
				{
					return Quantity * Price;
				}
			}

			private Literal _literal;
			public Literal LineTotalLiteral
			{
				get
				{
					if (_literal == null)
					{
						_literal = String.Format("{0:c}", LineTotal).ToLiteral();
					}

					return _literal;
				}
			}



			public static TableHeaderRow Header
			{
				get
				{
					var th = new TableHeaderRow();
					th.AddGeneratedTableHeaderCell("ID".ToLiteral());
					th.AddGeneratedTableHeaderCell("Item Name".ToLiteral());
					th.AddGeneratedTableHeaderCell("Price".ToLiteral());
					th.AddGeneratedTableHeaderCell("Quantity".ToLiteral());
					th.AddGeneratedTableHeaderCell("Line Total".ToLiteral());
					return th;
				}
			}


			public void Update()
			{
				LineTotalLiteral.Text = String.Format("{0:c}", LineTotal);
			}

			public SaleItem ToSaleItem()
			{
				var SaleItem = new SaleItem
									{
										Quantity = Quantity,
										ProductID = Prod.ProductID,
										Price = Prod.Price,
									};
				return SaleItem;
			}

		}

		private ClientControl clientControl;
		private SaleControl saleControl;

		private Button makeSaleBtn;
		

		protected void Page_Init(object sender, EventArgs e)
		{
			clientControl = new ClientControl();
			saleControl = new SaleControl();
			makeSaleBtn = new Button
								{
									Text="Confirm Sale",
								};
			makeSaleBtn.Command += new CommandEventHandler(makeSaleBtn_Command);
			

			contentPlaceholder.Controls.Add(clientControl);
			contentPlaceholder.Controls.Add(saleControl);
			contentPlaceholder.Controls.Add(makeSaleBtn);
		}

		

		protected void Page_Load(object sender, EventArgs e)
		{
			
		}

		protected void Page_PreRender(object sender, EventArgs e)
		{
			saleControl.UpdateAll();
		}

		void makeSaleBtn_Command(object sender, CommandEventArgs e)
		{
 			saleControl.UpdateAll();
			var sale = saleControl.ToSale();
			var client = clientControl.ToClient();

			var response = Service.GetResponse(sale, client);

			if(response.Success)
			{
				Alert.Show("Sale Committed", Alert.AlertMessageType.Message);
				Response.Redirect("/Dashboard.aspx");
			}
			else
			{
				Alert.Show("Failed: " + response.ErrorMessage, Alert.AlertMessageType.Error);
			}
		}

		#region service class
		private static class Service
		{
			private static string ServiceURL
			{
				get
				{
					return "http://localhost:51940/WCF/MakeASale/MakeASale.svc";
				}
			}

			private static ChannelFactory<IMakeASale> _factory;
			private static ChannelFactory<IMakeASale> Factory
			{
				get
				{
					if (_factory == null)
					{
						var ep = new EndpointAddress(ServiceURL);
						_factory = new ChannelFactory<IMakeASale>(new BasicHttpBinding(), ep);
					}
					return _factory;
				}
			}

			private static IMakeASale Client
			{
				get
				{
					return Factory.CreateChannel();
				}
			}

			public static MakeASaleResponse GetResponse(Sale sale, Client client)
			{
				MakeASaleRequest request = new MakeASaleRequest
												{
													TheSale = sale,
													TheClient = client,
												};
				return Client.MakeSale(request);
			}
		}
		#endregion service class
	}
}